package com.gitee.chili.leisure.server;

import com.gitee.chili.leisure.core.Packet;
import com.gitee.chili.leisure.model.MessageCmdEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * 消息解码器
 */
@Slf4j
public class MessageDecoder extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!(msg instanceof BinaryWebSocketFrame)) {
            log.error("违法消息 : {} ", msg.toString());
            // TODO 目前只处理了二进制消息，后续会加上文本处理，此处需要放行
            return;
        }

        // WebSocket 二进制消息会通过 HttpServerCodec 解码成 BinaryWebSocketFrame 类对象
        BinaryWebSocketFrame frame = (BinaryWebSocketFrame) msg;
        ByteBuf byteBuf = frame.content();

        // 读取消息的长度
        byteBuf.readShort();
        // 读取消息的编号
        int code = byteBuf.readShort();

        // 拿到消息体
        byte[] msgBody = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(msgBody);

        // 消息命令
        MessageCmdEnum.Command command = MessageCmdEnum.Command.forNumber(code);

        if (Objects.isNull(command)) {
            log.error("未能识别的消息");
            return;
        }

        // 将消息传递给下一个处理器
        ctx.fireChannelRead(Packet.newPacket(command, msgBody));
    }
}
